import socket
import serial

class AUTOLinkReceiver:
    """
    自动连接模块接收器，自动识别并且打包CRSF MAVlink MSP数据包，并调用回调函数进行处理数据。
    The automatic connection module receiver automatically recognizes and packages CRSF MAVlink MSP data packets,
    and calls callback functions to process the data.
    """
    def __init__(self, port, callback, host_baudrate_or_ip='0.0.0.0'):
        """
        port: 数据源，可以是UDP端口号或串口设备路径
        callback: 数据接收回调函数，接收到数据包时会调用此函数
        host_baudrate_or_ip: 如果port是UDP端口号，则这里是IP地址(如'127.0.0.1')；如果port是串口设备路径，则这里是波特率(如115200)
        """
        self.callback = callback
        self.buffer = bytearray()
        
        # 判断port是UDP端口还是串口
        if isinstance(port, int):
            # 假设port是UDP端口
            self.ip_address = host_baudrate_or_ip
            self.port = port
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            self.sock.bind((self.ip_address, self.port))
        elif isinstance(port, str):
            # 假设port是串口设备路径
            self.ser = serial.Serial(port, baudrate=int(host_baudrate_or_ip), timeout=1)
        else:
            raise ValueError("Port must be an integer (UDP) or a string (serial port)")

    def start_receiving(self):
        """开始接收数据"""
        while True:
            try:
                if hasattr(self, 'sock'):
                    # 从UDP套接字接收数据
                    data, _ = self.sock.recvfrom(1024)  # 一次读取1024字节
                elif hasattr(self, 'ser'):
                    # 从串口接收数据
                    data = self.ser.readall()  # 一次读取数据
                else:
                    raise Exception("No valid data source configured")

                #self.buffer.extend(data)  # 将接收到的数据添加到缓冲区
                if data:
                    hex_string = data.hex()
                    #print("data", hex_string) 
                    self.callback(hex_string)  # 调用回调函数处理数据
            except KeyboardInterrupt:
                print("接收到中断信号，停止接收数据")
                break
            except Exception as e:
                print(f"接收数据时发生错误: {e}")
                


    def write(self, data):
        """向数据源发送数据"""
        if hasattr(self, 'sock'):
            # 发送UDP数据
            self.sock.sendto(data, (self.ip_address, self.port))
        elif hasattr(self, 'ser'):
            # 发送串口数据
            self.ser.write(data)
        else:
            raise Exception("No valid data source configured")



# 使用示例
if __name__ == "__main__":
    def callback(packet):
        print(f"Received MAVLink packet: {packet}")
        pass

    # 假设数据源是UDP连接，端口为14550
    port_udp = 14550
    ip = '192.168.1.100'
    receiver_udp = AUTOLinkReceiver(port_udp, callback, host_baudrate_or_ip=ip)
    receiver_udp.start_receiving()

    # 或者假设数据源是串口，设备路径为'/dev/ttyUSB0'
    port_serial = '/dev/ttyUSB0'
    baudrate = 115200
    receiver_serial = AUTOLinkReceiver(port_serial, callback, host_baudrate_or_ip=baudrate)
    receiver_serial.start_receiving()

    # 发送数据
    data = b'\x01\x02\x03\x04'
    receiver_udp.write(data)
    receiver_serial.write(data)
